home *** CD-ROM | disk | FTP | other *** search
/ World of Video / World of Video.iso / gfxprograms / 3dprograms / t3dlib / source / write.c < prev    next >
C/C++ Source or Header  |  1995-02-13  |  19KB  |  713 lines

  1. /* write.c - dump the internal database to a TTDDD file
  2.  *         - written by Glenn M. Lewis - 7/19/91
  3.  */
  4.  
  5. static char rcs_id[] = "$Id: write.c,v 1.22 1993/12/11 22:22:19 glewis Exp $";
  6.  
  7. #include <stdio.h>
  8. #include <ctype.h>
  9. #include "t3dlib.h"
  10. #ifdef __STDC__
  11. #include <stdlib.h>
  12. #include <strings.h>
  13. #include "write_protos.h"
  14. #endif
  15.  
  16. static void process_DESC();
  17. static void process_EXTR();
  18. static void process_INFO();
  19. static void process_OBJ();
  20. static void process_ISTG();
  21.  
  22. /* Two-space tabs */
  23. #define TABSTOP "  "
  24.  
  25. static FILE *out;
  26. static char tab[133], strin[133];
  27. static int num_OBJ, num_DESC, num_TOBJ;
  28. static int cur_level, cur_objnum;
  29. static int prntline;
  30.  
  31. static struct save_hier {
  32.     int objnum;
  33.     struct save_hier *next;
  34. } *root = 0;
  35. typedef struct save_hier HIER;
  36.  
  37. /* Here are a few necessary utilities */
  38.  
  39. static void indent()
  40. {
  41.     strcat(tab, TABSTOP);
  42. }
  43.  
  44. static void outdent()
  45. {
  46.     register int i = strlen(tab) - strlen(TABSTOP);
  47.     if (i<0) {
  48.         fprintf(stderr, "Whoa, Glenn!  You blew it!\n");
  49.         tab[0] = '\0';
  50.         return;
  51.     }
  52.     tab[i] = '\0';
  53. }
  54.  
  55. #define ROUNDIT(x) ((double)((long)(x*1000.0+0.5-((x)<0.0)))/1000.0)
  56.  
  57. static void send_XYZ(f)            /* Print a common string */
  58. XYZ_st *f;
  59. {
  60.     fprintf(out, " X=%.12g",   ROUNDIT(f->x));
  61.     fprintf(out, " Y=%.12g",   ROUNDIT(f->y));
  62.     fprintf(out, " Z=%.12g\n", ROUNDIT(f->z));
  63. }
  64.  
  65. static void stage_RGB(rgb)            /* Print a common string */
  66. XYZ_st *rgb;
  67. {
  68.     fprintf(out, " R=%.12g",   ROUNDIT(rgb->x));
  69.     fprintf(out, " G=%.12g",   ROUNDIT(rgb->y));
  70.     fprintf(out, " B=%.12g ",  ROUNDIT(rgb->z));
  71. }
  72.  
  73. static void send_RGB(rgb)            /* Print a common string */
  74. RGB_st *rgb;
  75. {
  76.     fprintf(out, " R=%u",   rgb->r);
  77.     fprintf(out, " G=%u",   rgb->g);
  78.     fprintf(out, " B=%u\n", rgb->b);
  79. }
  80.  
  81. /********************/
  82. /* The MAIN section */
  83. /********************/
  84.  
  85. int write_TTDDD(world, file)
  86. WORLD *world;
  87. FILE *file;
  88. {
  89.     register OBJECT *o;
  90.  
  91.     if (!(out=file) || !world) return(0);    /* File not open */
  92.  
  93.     tab[0] = '\0';
  94.     num_OBJ = num_DESC = num_TOBJ = 0;
  95.  
  96.     fprintf(out, "%% T3DLIB %s - Written by Glenn M. Lewis - %s\n\n",
  97.         REV, __DATE__);
  98.     if (world->info) process_INFO(world->info);
  99.     if (world->istg) process_ISTG(world->istg);
  100.     for (o=world->object; o; o=o->next)
  101.         process_OBJ(o);
  102.     return(1);
  103. }
  104.  
  105. static void process_INFO(info)
  106. INFO *info;
  107. {
  108.     register int i;
  109.  
  110.     fprintf(out, "%sINFO Begin\n", tab);
  111.     indent();
  112.     for (i=0; i<8; i++)
  113.         if (info->brsh[i][0])
  114.             fprintf(out, "%sBRSH[%d]=\"%s\"\n", tab, i, info->brsh[i]);
  115.  
  116.     for (i=0; i<8; i++)
  117.         if (info->stnc[i][0])
  118.             fprintf(out, "%sSTNC[%d]=\"%s\"\n", tab, i, info->stnc[i]);
  119.  
  120.     for (i=0; i<8; i++)
  121.         if (info->txtr[i][0])
  122.             fprintf(out, "%sTXTR[%d]=\"%s\"\n", tab, i, info->txtr[i]);
  123.  
  124.     if (info->obsv) {
  125.         fprintf(out, "%sOBSV Camera", tab); send_XYZ(&info->obsv->came);
  126.         fprintf(out, "%sOBSV Rotate", tab); send_XYZ(&info->obsv->rota);
  127.         fprintf(out, "%sOBSV Focal  %.12g\n", tab, info->obsv->foca);
  128.     }
  129.  
  130.     if (info->otrk[0]) fprintf(out, "%sOTRK \"%s\"\n", tab, info->otrk);
  131.  
  132.     if (info->ostr) {
  133.         if (info->ostr->path[0])
  134.             fprintf(out, "%sOSTR Path \"%s\"\n", tab, info->ostr->path);
  135.         fprintf(out, "%sOSTR Translate", tab); send_XYZ(&info->ostr->tran);
  136.         fprintf(out, "%sOSTR Rotate   ", tab); send_XYZ(&info->ostr->rota);
  137.         fprintf(out, "%sOSTR Scale    ", tab); send_XYZ(&info->ostr->scal);
  138.         i = info->ostr->info;
  139.         strin[0] = '\0';
  140.         if (i&(1<<0))  strcat(strin, " ABS_TRA");
  141.         if (i&(1<<1))  strcat(strin, " ABS_ROT");
  142.         if (i&(1<<2))  strcat(strin, " ABS_SCL");
  143.         if (i&(1<<4))  strcat(strin, " LOC_TRA");
  144.         if (i&(1<<5))  strcat(strin, " LOC_ROT");
  145.         if (i&(1<<6))  strcat(strin, " LOC_SCL");
  146.         if (i&(1<<8))  strcat(strin, " X_ALIGN");
  147.         if (i&(1<<9))  strcat(strin, " Y_ALIGN");
  148.         if (i&(1<<10)) strcat(strin, " Z_ALIGN");
  149.         if (i&(1<<12)) strcat(strin, " FOLLOW_ME");
  150.         fprintf(out, "%sOSTR Info%s\n", tab, strin);
  151.     }
  152.  
  153.     if (info->fade) {
  154.         fprintf(out, "%sFADE FadeAt %.12g\n", tab, info->fade->at);
  155.         fprintf(out, "%sFADE FadeBy %.12g\n", tab, info->fade->by);
  156.         fprintf(out, "%sFADE FadeTo", tab); send_RGB(&info->fade->to);
  157.     }
  158.  
  159.     if (info->skyc) {
  160.         fprintf(out, "%sSKYC Horizon", tab); send_RGB(&info->skyc->hori);
  161.         fprintf(out, "%sSKYC Zenith ", tab); send_RGB(&info->skyc->zeni);
  162.     }
  163.  
  164.     if (info->ambi)
  165.         { fprintf(out, "%sAMBI", tab); send_RGB(info->ambi); }
  166.  
  167.     if (info->glb0)
  168.         for (i=0; i<8; i++)
  169.             fprintf(out, "%sGLB0[%d]=%u\n", tab, i, info->glb0[i]);
  170.  
  171.     outdent();
  172.     fprintf(out, "%sEnd INFO\n", tab);
  173. }
  174.  
  175. static void process_OBJ(obj)
  176. register OBJECT *obj;
  177. {
  178.     register HIER *p;
  179.     num_OBJ++;
  180.     fprintf(out, "%sOBJ Begin \"Hierarchy %d\"\n", tab, num_OBJ);
  181.     num_DESC = num_TOBJ = 0;        /* Reset counters */
  182.     cur_level = 0;
  183.     cur_objnum = 1;
  184.     prntline = 1;
  185.  
  186.     if (obj->extr) process_EXTR(obj->extr);
  187.     else process_DESC(obj);
  188.  
  189.     while (root) {                /* This should happen at most once. */
  190.         p = root->next;
  191.         free((char *)root);        /* Delete this from list */
  192.         root = p;
  193.         outdent();
  194.     }
  195.  
  196.     fprintf(out, "%sEnd OBJ   \"Hierarchy %d\"\n", tab, num_OBJ);
  197. }
  198.  
  199. static void process_TOBJ()
  200. {
  201.     register HIER *p;
  202.     if (num_DESC-num_TOBJ < cur_level) {    /* Pop old level off HIER */
  203.         cur_level--;
  204.         cur_objnum = root->objnum;
  205.         p = root->next;
  206.         free((char *)root);    /* Delete from list */
  207.         root = p;
  208.         outdent();    /* Pretty file formatting */
  209.     }
  210.     fprintf(out, "%sTOBJ       \"Object %d at level %d of hierarchy %d\"\n",
  211.         tab, cur_objnum-1, num_DESC-num_TOBJ, num_OBJ);
  212.     num_TOBJ++;
  213.     prntline = 1;
  214. }
  215.  
  216. static void process_EXTR(extr)
  217. EXTR *extr;
  218. {
  219.     if (!prntline) fprintf(out, "\n");    /* Print one anyway */
  220.     indent();
  221.     num_DESC++;
  222.  
  223.     fprintf(out, "%sEXTR Begin \"Object %d at level %d of hierarchy %d\"\n",
  224.         tab, cur_objnum, num_DESC-num_TOBJ, num_OBJ);
  225.     indent();
  226.     fprintf(out, "%sMTRX Translate", tab); send_XYZ(&extr->mtrx.tran);
  227.     fprintf(out, "%sMTRX Scale    ", tab); send_XYZ(&extr->mtrx.scal);
  228.     fprintf(out, "%sMTRX Rotate", tab);
  229.     fprintf(out, " %.12g %.12g %.12g",
  230.         extr->mtrx.rota1.x,
  231.         extr->mtrx.rota1.y,
  232.         extr->mtrx.rota1.z);
  233.     fprintf(out, " %.12g %.12g %.12g",
  234.         extr->mtrx.rota2.x,
  235.         extr->mtrx.rota2.y,
  236.         extr->mtrx.rota2.z);
  237.     fprintf(out, " %.12g %.12g %.12g",
  238.         extr->mtrx.rota3.x,
  239.         extr->mtrx.rota3.y,
  240.         extr->mtrx.rota3.z);
  241.     fprintf(out, "\n");
  242.  
  243.     fprintf(out, "%sLOAD \"%s\"\n", tab, extr->filename);
  244.     outdent();
  245.     fprintf(out, "%sEnd EXTR   \"Object %d at level %d of hierarchy %d\"\n",
  246.         tab, cur_objnum, num_DESC-num_TOBJ, num_OBJ);
  247.  
  248.     num_TOBJ++;
  249.     cur_objnum++;
  250.     outdent();
  251.     prntline = 1;
  252. }
  253.  
  254. static void process_DESC(object)
  255. OBJECT *object;
  256. {
  257.     register int i, j;
  258.     register HIER *p;
  259.     register OBJECT *obj;
  260.     register DESC *desc = object->desc;
  261.     FGRP *fgrp;
  262.  
  263.     num_DESC++;
  264.     if (num_DESC-num_TOBJ > cur_level) {    /* Push new level in HIER */
  265.         if (!prntline) fprintf(out, "\n");    /* Print one anyway */
  266.         if (!(p = (HIER*)malloc(sizeof(HIER)))) {
  267.             fprintf(stderr, "ERROR!  Out of memory.\n*** ABORT ***\n");
  268.             exit(20);
  269.         }
  270.         p->next = root;        /* Insert into list */
  271.         root = p;
  272.         root->objnum = cur_objnum;
  273.         cur_level++;
  274.         cur_objnum = 1;
  275.         indent();    /* Pretty file formatting */
  276.     }
  277.  
  278.     fprintf(out, "%sDESC Begin \"Object %d at level %d of hierarchy %d\"\n",
  279.         tab, cur_objnum, num_DESC-num_TOBJ, num_OBJ);
  280.     indent();
  281.  
  282.     if (desc->name[0]) fprintf(out, "%sNAME \"%s\"\n", tab, desc->name);
  283.  
  284.     if (desc->shap) {
  285.         fprintf(out, "%sSHAP Shape = %u\n", tab, desc->shap[0]);
  286.         fprintf(out, "%sSHAP Lamp  = %u\n", tab, desc->shap[1]);
  287.     }
  288.  
  289.     if (desc->posi)
  290.         { fprintf(out, "%sPOSI", tab); send_XYZ(desc->posi); }
  291.  
  292.     if (desc->axis) {
  293.         fprintf(out, "%sAXIS XAxis", tab); send_XYZ(&desc->axis->xaxi);
  294.         fprintf(out, "%sAXIS YAxis", tab); send_XYZ(&desc->axis->yaxi);
  295.         fprintf(out, "%sAXIS ZAxis", tab); send_XYZ(&desc->axis->zaxi);
  296.     }
  297.  
  298.     if (desc->size)
  299.         { fprintf(out, "%sSIZE", tab); send_XYZ(desc->size); }
  300.  
  301.     if (desc->pcount) {
  302.         fprintf(out, "%sPNTS PCount %u\n", tab, desc->pcount);
  303.         for (i=0; i<desc->pcount; i++) {
  304.             fprintf(out, "%sPNTS Point[%d]", tab, i);
  305.             send_XYZ(&desc->pnts[i]);
  306.         }
  307.     }
  308.  
  309.     if (desc->ecount) {
  310.         fprintf(out, "%sEDGE ECount %u\n", tab, desc->ecount);
  311.         for (i=0; i<desc->ecount; i++) {
  312.             fprintf(out, "%sEDGE Edge[%d] %u %u\n", tab, i,
  313.                 desc->edge[i<<1], desc->edge[(i<<1)+1]);
  314.         }
  315.     }
  316.  
  317.     if (desc->eflg) {
  318.         fprintf(out, "%sEFLG Count %u\n", tab, desc->eflg->num);
  319.         for (i=0; i<desc->eflg->num; i++) {
  320.             fprintf(out, "%sEFLG Eflg[%d]=%u\n", tab, i, desc->eflg->eflg[i]);
  321.         }
  322.     }
  323.  
  324.     if (desc->fcount) {
  325.         fprintf(out, "%sFACE TCount %u\n", tab, desc->fcount);
  326.         for (i=0; i<desc->fcount; i++) {
  327.             fprintf(out, "%sFACE Connect[%u] %u %u %u\n", tab, i,
  328.                 desc->face[i*3], desc->face[i*3+1], desc->face[i*3+2]);
  329.         }
  330.     }
  331.  
  332.     for (fgrp=desc->fgrp; fgrp; fgrp=fgrp->next) {
  333.         fprintf(out, "%sFGRP Name \"%s\"\n", tab, fgrp->name);
  334.         fprintf(out, "%sFGRP Count %u\n", tab, fgrp->num);
  335.         for (i=0; i<fgrp->num; i++)
  336.             fprintf(out, "%sFGRP Face[%u]=%u\n", tab, i, fgrp->face[i]);
  337.     }
  338.  
  339.     for (i=0; i<4; i++) {
  340.         if (!desc->txt2[i]) continue;
  341.         fprintf(out, "%sTXT2[%u] Flags %u\n", tab, i, desc->txt2[i]->Flags);
  342.         fprintf(out, "%sTXT2[%u] Translate",tab, i);
  343.         send_XYZ(&desc->txt2[i]->TAxis.tran);
  344.         fprintf(out, "%sTXT2[%u] XAxis",tab, i);
  345.         send_XYZ(&desc->txt2[i]->TAxis.rota1);
  346.         fprintf(out, "%sTXT2[%u] YAxis",tab, i);
  347.         send_XYZ(&desc->txt2[i]->TAxis.rota2);
  348.         fprintf(out, "%sTXT2[%u] ZAxis",tab, i);
  349.         send_XYZ(&desc->txt2[i]->TAxis.rota3);
  350.         fprintf(out, "%sTXT2[%u] Scale",tab, i);
  351.         send_XYZ(&desc->txt2[i]->TAxis.scal);
  352.         for (j = 0; j < 16; j++) {
  353.             fprintf(out, "%sTXT2[%u] Params[%u]=%.12g\n", tab, i, j, 
  354.             desc->txt2[i]->Params[j]);
  355.         }
  356.         for (j = 0; j < 16; j++) {
  357.             fprintf(out, "%sTXT2[%u] PFlags[%u]=%u\n", tab, i, j, 
  358.             desc->txt2[i]->PFlags[j]);
  359.         }
  360.         fprintf(out, "%sTXT2[%u] SubGroup \"%s\"\n", tab, i, 
  361.             desc->txt2[i]->SubName);
  362.         fprintf(out, "%sTXT2[%u] Texture \"%s\"\n",tab, i, 
  363.             desc->txt2[i]->Name);
  364.     }
  365.  
  366.     if (desc->colr) { fprintf(out, "%sCOLR", tab); send_RGB(desc->colr); }
  367.  
  368.     if (desc->refl) { fprintf(out, "%sREFL", tab); send_RGB(desc->refl); }
  369.  
  370.     if (desc->tran) { fprintf(out, "%sTRAN", tab); send_RGB(desc->tran); }
  371.  
  372.     if (desc->spc1) { fprintf(out, "%sSPC1", tab); send_RGB(desc->spc1); }
  373.  
  374.     if (desc->fcount) {
  375.         fprintf(out, "%sCLST Count %u\n", tab, desc->fcount);
  376.         for (i=0; i<desc->fcount; i++) {
  377. #if 0
  378. /* Never skip printing a CLST value - GML - 3/27/92 */
  379.             if (desc->colr) {
  380.                 if (desc->clst[i*3  ]==desc->colr->r &&
  381.                     desc->clst[i*3+1]==desc->colr->g &&
  382.                     desc->clst[i*3+2]==desc->colr->b) continue; /* Skip */
  383.             } else {
  384.                 if (desc->clst[i*3  ]==240 &&
  385.                     desc->clst[i*3+1]==240 &&
  386.                     desc->clst[i*3+2]==240) continue;    /* Skip this one */
  387.             }
  388. #endif
  389.             fprintf(out, "%sCLST Color[%u]", tab, i);
  390.             send_RGB((RGB_st*)&desc->clst[i*3]);
  391.         }
  392.         fprintf(out, "%sRLST Count %u\n", tab, desc->fcount);
  393.         for (i=0; i<desc->fcount; i++) {
  394.             if (desc->refl) {
  395.                 if (desc->rlst[i*3  ]==desc->refl->r &&
  396.                     desc->rlst[i*3+1]==desc->refl->g &&
  397.                     desc->rlst[i*3+2]==desc->refl->b) continue; /* Skip */
  398.             } else {
  399.                 if (desc->rlst[i*3  ]==0 &&
  400.                     desc->rlst[i*3+1]==0 &&
  401.                     desc->rlst[i*3+2]==0) continue;    /* Skip this one */
  402.             }
  403.             fprintf(out, "%sRLST Color[%u]", tab, i);
  404.             send_RGB((RGB_st*)&desc->rlst[i*3]);
  405.         }
  406.         fprintf(out, "%sTLST Count %u\n", tab, desc->fcount);
  407.         for (i=0; i<desc->fcount; i++) {
  408.             if (desc->tran) {
  409.                 if (desc->tlst[i*3  ]==desc->tran->r &&
  410.                     desc->tlst[i*3+1]==desc->tran->g &&
  411.                     desc->tlst[i*3+2]==desc->tran->b) continue; /* Skip */
  412.             } else {
  413.                 if (desc->tlst[i*3  ]==0 &&
  414.                     desc->tlst[i*3+1]==0 &&
  415.                     desc->tlst[i*3+2]==0) continue;    /* Skip this one */
  416.             }
  417.             fprintf(out, "%sTLST Color[%u]", tab, i);
  418.             send_RGB((RGB_st*)&desc->tlst[i*3]);
  419.         }
  420.     }
  421.  
  422.     if (desc->tpar) {
  423.         for (i=0; i<16; i++)
  424.             fprintf(out, "%sTPAR[%u]=%.12g\n", tab, i, desc->tpar[i]);
  425.     }
  426.  
  427.     if (desc->surf) {
  428.         for (i=0; i<5; i++)
  429.             fprintf(out, "%sSURF[%u]=%d\n", tab, i, desc->surf[i]);
  430.     }
  431.  
  432.     if (desc->mttr) {
  433.         fprintf(out, "%sMTTR Type =%u\n", tab, desc->mttr->type);
  434.         fprintf(out, "%sMTTR Index=%.12g\n", tab, (double)desc->mttr->indx);
  435.     }
  436.  
  437.     if (desc->spec) {
  438.         fprintf(out, "%sSPEC Spec=%u\n", tab, desc->spec[0]);
  439.         fprintf(out, "%sSPEC Hard=%u\n", tab, desc->spec[1]);
  440.     }
  441.  
  442.     if (desc->prp0) {
  443.         for (i=0; i<6; i++)
  444.             fprintf(out, "%sPRP0[%u]=%u\n", tab, i, desc->prp0[i]);
  445.     }
  446.  
  447.     if (desc->prp1) {
  448.         for (i=0; i<8; i++)
  449.             fprintf(out, "%sPRP1[%u]=%u\n", tab, i, desc->prp1[i]);
  450.     }
  451.  
  452.     if (desc->ints)
  453.         fprintf(out, "%sINTS=%.12g\n", tab, desc->ints);
  454.  
  455.     if (desc->int1) { fprintf(out, "%sINT1", tab); send_XYZ(desc->int1); }
  456.  
  457.     if (desc->stry) {
  458.         fprintf(out, "%sSTRY Path \"%s\"\n", tab, desc->stry->path);
  459.         fprintf(out, "%sSTRY Translate", tab); send_XYZ(&desc->stry->tran);
  460.         fprintf(out, "%sSTRY Rotate   ", tab); send_XYZ(&desc->stry->rota);
  461.         fprintf(out, "%sSTRY Scale    ", tab); send_XYZ(&desc->stry->scal);
  462.         i = desc->stry->info;
  463.         strin[0] = '\0';
  464.         if (i&(1<<0))  strcat(strin, " ABS_TRA");
  465.         if (i&(1<<1))  strcat(strin, " ABS_ROT");
  466.         if (i&(1<<2))  strcat(strin, " ABS_SCL");
  467.         if (i&(1<<4))  strcat(strin, " LOC_TRA");
  468.         if (i&(1<<5))  strcat(strin, " LOC_ROT");
  469.         if (i&(1<<6))  strcat(strin, " LOC_SCL");
  470.         if (i&(1<<8))  strcat(strin, " X_ALIGN");
  471.         if (i&(1<<9))  strcat(strin, " Y_ALIGN");
  472.         if (i&(1<<10)) strcat(strin, " Z_ALIGN");
  473.         if (i&(1<<12)) strcat(strin, " FOLLOW_ME");
  474.         fprintf(out, "%sSTRY Info%s\n", tab, strin);
  475.     }
  476.  
  477.     outdent();
  478.     fprintf(out, "%sEnd DESC   \"Object %d at level %d of hierarchy %d\"\n",
  479.         tab, cur_objnum, num_DESC-num_TOBJ, num_OBJ);
  480.  
  481.     for (obj=object->child; obj; obj=obj->next) {
  482.         if (obj->extr) process_EXTR(obj->extr);
  483.         else process_DESC(obj);
  484.     }
  485.  
  486.     cur_objnum++;
  487.     prntline = 0;
  488.     process_TOBJ();
  489. }
  490.  
  491. /************************************************************************/
  492. /* New code to write staging file - written by Glenn M. Lewis - 8/11/92 */
  493. /************************************************************************/
  494.  
  495. static void process_OSIZ();
  496. static void process_POSN();
  497. static void process_ALGN();
  498. static void process_PALN();
  499. static void process_TALN();
  500. static void process_PTH2();
  501. static void process_GLB2();
  502. static void process_AXIS();
  503. static void process_LITE();
  504. static void process_FILE();
  505.  
  506. static void process_ISTG(istg)
  507. register ISTG *istg;
  508. {
  509.     register SOBJ *sobj;
  510.  
  511.     fprintf(out, "\n%sISTG Begin\n", tab);
  512.  
  513.     indent();
  514.  
  515.     fprintf(out, "\n%sMAXF %u\t%% Max. frames\n", tab, istg->maxf);
  516.  
  517.     /* Sort the SOBJ's first? */
  518.  
  519. /* Here is the main loop: */
  520.     for (sobj=istg->head; sobj; sobj=sobj->next) {
  521.         fprintf(out, "\n%sSOBJ Begin\n", tab);
  522.         indent();
  523.  
  524.         fprintf(out, "\n%sNAME \"%s\"\n", tab, sobj->name);
  525.         fprintf(out, "%sSTGF %u\n", tab, sobj->stgf);
  526.         if (sobj->glb2) process_GLB2(sobj);
  527.         if (sobj->file) process_FILE(sobj);
  528.         if (sobj->lite) process_LITE(sobj);
  529.         if (sobj->axis) process_AXIS(sobj);
  530.         if (sobj->posn) process_POSN(sobj);
  531.         if (sobj->algn) process_ALGN(sobj);
  532.         if (sobj->osiz) process_OSIZ(sobj);
  533.         if (sobj->paln) process_PALN(sobj);
  534.         if (sobj->taln) process_TALN(sobj);
  535.         if (sobj->pth2) process_PTH2(sobj);
  536.  
  537.         outdent();
  538.         fprintf(out, "\n%sEND SOBJ\n", tab);
  539.     }
  540.  
  541. /* All done. */
  542.     outdent();
  543.     fprintf(out, "\nEND ISTG\n\n");
  544. }
  545.  
  546. static void process_OSIZ(sobj)
  547. SOBJ *sobj;
  548. {
  549.     register OSIZ *osiz;
  550.  
  551.     fputs("\n", out);
  552.     for (osiz=sobj->osiz; osiz; osiz=osiz->next) {
  553.         fprintf(out, "%sOSIZ FLAGS=%u ", tab, osiz->flags);
  554.         fprintf(out, "START=%u ", osiz->start);
  555.         fprintf(out, "STOP=%u SIZE", osiz->stop);
  556.         send_XYZ(&osiz->size);
  557.     }
  558. }
  559.  
  560. static void process_POSN(sobj)
  561. SOBJ *sobj;
  562. {
  563.     register POSN *posn;
  564.  
  565.     fputs("\n", out);
  566.     for (posn=sobj->posn; posn; posn=posn->next) {
  567.         fprintf(out, "%sPOSN FLAGS %u ", tab, posn->flags);
  568.         fprintf(out, "START=%u ", posn->start);
  569.         fprintf(out, "STOP=%u POSN", posn->stop);
  570.         send_XYZ(&posn->posn);
  571.     }
  572. }
  573.  
  574. static void process_ALGN(sobj)
  575. SOBJ *sobj;
  576. {
  577.     register ALGN *algn;
  578.  
  579.     fputs("\n", out);
  580.     for (algn=sobj->algn; algn; algn=algn->next) {
  581.         fprintf(out, "%sALGN FLAGS=%u ", tab, algn->flags);
  582.         fprintf(out, "START=%u ", algn->start);
  583.         fprintf(out, "STOP=%u ALGN", algn->stop);
  584.         send_XYZ(&algn->algn);
  585.     }
  586. }
  587.  
  588. static void process_PALN(sobj)
  589. SOBJ *sobj;
  590. {
  591.     register PALN *paln;
  592.  
  593.     fputs("\n", out);
  594.     for (paln=sobj->paln; paln; paln=paln->next) {
  595.         fprintf(out, "%sPALN FLAGS %u ", tab, paln->flags);
  596.         fprintf(out, "START=%u ", paln->start);
  597.         fprintf(out, "STOP=%u\n", paln->stop);
  598.     }
  599. }
  600.  
  601. static void process_TALN(sobj)
  602. SOBJ *sobj;
  603. {
  604.     register TALN *taln;
  605.  
  606.     fputs("\n", out);
  607.     for (taln=sobj->taln; taln; taln=taln->next) {
  608.         fprintf(out, "%sTALN FLAGS=%u ", tab, taln->flags);
  609.         fprintf(out, "START=%u ", taln->start);
  610.         fprintf(out, "STOP=%u ", taln->stop);
  611.         fprintf(out, "INITIAL_Y=%.12g ", taln->initial_y);
  612.         fprintf(out, "FINAL_Y=%.12g ", taln->final_y);
  613.         fprintf(out, "NAME=\"%s\"\n", taln->trackobj);
  614.     }
  615. }
  616.  
  617. static void process_PTH2(sobj)
  618. SOBJ *sobj;
  619. {
  620.     register PTH2 *pth2;
  621.  
  622.     fputs("\n", out);
  623.     for (pth2=sobj->pth2; pth2; pth2=pth2->next) {
  624.         fprintf(out, "%sPTH2 FLAGS=%u ", tab, pth2->flags);
  625.         fprintf(out, "START=%u ", pth2->start);
  626.         fprintf(out, "STOP=%u ", pth2->stop);
  627.         fprintf(out, "ACCEL=%lu ", pth2->acceleration_frames);
  628.         fprintf(out, "START_SPEED=%.12g ", pth2->start_speed);
  629.         fprintf(out, "DECEL=%lu ", pth2->deacceleration_frames);
  630.         fprintf(out, "END_SPEED=%.12g ", pth2->end_speed);
  631.         fprintf(out, "PATH=\"%s\"\n", pth2->path);
  632.     }
  633. }
  634.  
  635. static void process_GLB2(sobj)
  636. SOBJ *sobj;
  637. {
  638.     register GLB2 *glb2;
  639.  
  640.     fputs("\n", out);
  641.     for (glb2=sobj->glb2; glb2; glb2=glb2->next) {
  642.         fprintf(out, "%sGLB2 FLAGS=%u ", tab, glb2->flags);
  643.         fprintf(out, "START=%u ", glb2->start);
  644.         fprintf(out, "STOP=%u ", glb2->stop);
  645.         fprintf(out, "SKY_BLEND=%lu ", glb2->sky_blending);
  646.         fprintf(out, "STARFIELD=%.12g ", glb2->starfield);
  647.         fprintf(out, "TRANSITION=%lu ", glb2->transition);
  648.         fprintf(out, "AMBIENT ");
  649.         stage_RGB(&glb2->ambient);
  650.         fprintf(out, "HORIZON ");
  651.         stage_RGB(&glb2->horizon);
  652.         fprintf(out, "ZENITH1 ");
  653.         stage_RGB(&glb2->zenith1);
  654.         fprintf(out, "ZENITH2 ");
  655.         stage_RGB(&glb2->zenith2);
  656.         fprintf(out, "FOG_COL ");
  657.         stage_RGB(&glb2->fog_color);
  658.         fprintf(out, "FOG_BOTTOM=%.12g ", glb2->fog_bottom);
  659.         fprintf(out, "FOG_TOP=%.12g ", glb2->fog_top);
  660.         fprintf(out, "FOG_LENGTH=%.12g ", glb2->fog_length);
  661.         fprintf(out, "BRUSH_SEQ=%lu ", glb2->brush_seq);
  662.         fprintf(out, "BACKDROP_SEQ=%lu ", glb2->backdrop_seq);
  663.         fprintf(out, "BACKDROP=\"%s\" ", glb2->backdrop);
  664.         fprintf(out, "GLOBALBRUSH=\"%s\"\n", glb2->globalbrush);
  665.     }
  666. }
  667.  
  668. static void process_AXIS(sobj)
  669. SOBJ *sobj;
  670. {
  671.     register SAXIS *axis;
  672.  
  673.     fputs("\n", out);
  674.     for (axis=sobj->axis; axis; axis=axis->next) {
  675.         fprintf(out, "%sAXIS FLAGS=%u ", tab, axis->flags);
  676.         fprintf(out, "START=%u ", axis->start);
  677.         fprintf(out, "STOP=%u\n", axis->stop);
  678.     }
  679. }
  680.  
  681. static void process_LITE(sobj)
  682. SOBJ *sobj;
  683. {
  684.     register LITE *lite;
  685.  
  686.     fputs("\n", out);
  687.     for (lite=sobj->lite; lite; lite=lite->next) {
  688.         fprintf(out, "%sLITE FLAGS %u ", tab, lite->flags);
  689.         fprintf(out, "START=%u ", lite->start);
  690.         fprintf(out, "STOP=%u ", lite->stop);
  691.         fprintf(out, "COLOR ");
  692.         stage_RGB(&lite->color);
  693.         fprintf(out, "TRANSITION=%lu\n", lite->transition);
  694.     }
  695. }
  696.  
  697. static void process_FILE(sobj)
  698. SOBJ *sobj;
  699. {
  700.     register SFILE *file;
  701.  
  702.     fputs("\n", out);
  703.     for (file=sobj->file; file; file=file->next) {
  704.         fprintf(out, "%sFILE FLAGS=%u ", tab, file->flags);
  705.         fprintf(out, "START=%u ", file->start);
  706.         fprintf(out, "STOP=%u ", file->stop);
  707.         fprintf(out, "CYCLES=%.12g ", file->cycles_to_perform);
  708.         fprintf(out, "INITIAL_PHASE=%.12g ", file->initial_cycle_phase);
  709.         fprintf(out, "TRANSITION=%lu ", file->transition);
  710.         fprintf(out, "NAME=\"%s\"\n", file->object_description);
  711.     }
  712. }
  713.